package com.lsa.helpers.tree;

import java.util.Map;

import com.lsa.helpers.Pair;
import com.lsa.helpers.tree.binary.InfixBinaryTreeWalker;
import com.lsa.helpers.tree.binary.PostfixBinaryTreeWalker;
import com.lsa.helpers.tree.binary.PrefixBinaryTreeWalker;

import junit.framework.Assert;
import junit.framework.TestCase;

public class TestTraversals extends TestCase
{
    private final class OrderVisitor implements ITreeVisitor<Pair<String, Object>>
    {
        private int order = 1;
        @Override
        public void visit(ITreeNode<Pair<String, Object>> node) throws Exception
        {
            String label = node.getData().getFirst() + ":" + order;
            ++order;
            node.getData().setSecond(label);
        }
    }
    
    private final class LeafNumberingVisitor implements ITreeVisitor<Pair<String, Object>>
    {
        private int leafNumber = 1;
        @Override
        public void visit(ITreeNode<Pair<String, Object>> node) throws Exception
        {
            if (node.getChildren().size() == 0){
                String label = node.getData().getSecond() + " " + leafNumber;
                ++leafNumber;
                node.getData().setSecond(label);
            }
        }
    }

    public void testInfixOrder(){
        ITree<Pair<String, Object>> simpleTree = null;
        try
        {
            simpleTree = TgfTreeFactory.readStringTreeFromFile("data/binaryTree25.tgf");
            PrefixBinaryTreeWalker<Pair<String, Object>> prefixBinaryTreeWalker = new PrefixBinaryTreeWalker<Pair<String, Object>>(new OrderVisitor());
            prefixBinaryTreeWalker.walk(simpleTree.getRoot());
            TgfTreeFactory.saveStringTreeAsTgf(simpleTree, "data/binaryTree25PrefixTraversed.tgf");
            
            simpleTree = TgfTreeFactory.readStringTreeFromFile("data/binaryTree25.tgf");
            InfixBinaryTreeWalker<Pair<String, Object>> infixBinaryTreeWalker = new InfixBinaryTreeWalker<Pair<String, Object>>(new OrderVisitor());
            infixBinaryTreeWalker.walk(simpleTree.getRoot());
            TgfTreeFactory.saveStringTreeAsTgf(simpleTree, "data/binaryTree25InfixTraversed.tgf");
            
            simpleTree = TgfTreeFactory.readStringTreeFromFile("data/binaryTree25.tgf");
            PostfixBinaryTreeWalker<Pair<String, Object>> postfixBinaryTreeWalker = new PostfixBinaryTreeWalker<Pair<String, Object>>(new OrderVisitor());
            postfixBinaryTreeWalker.walk(simpleTree.getRoot());
            TgfTreeFactory.saveStringTreeAsTgf(simpleTree, "data/binaryTree25PostifxTraversed.tgf");
            
            LeafCountingWalker<Pair<String, Object>> leafCounter = new LeafCountingWalker<Pair<String, Object>>();
            leafCounter.walk(simpleTree.getRoot());
            System.out.println("binaryTree25.tgf leaf count:" + leafCounter.getLeafCount());
            
            simpleTree = TgfTreeFactory.readStringTreeFromFile("data/randomTree30.tgf");
            TreeWalker<Pair<String, Object>> treeWalker = new TreeWalker<Pair<String, Object>>(new LeafNumberingVisitor());
            treeWalker.walk(simpleTree.getRoot());
            TgfTreeFactory.saveStringTreeAsTgf(simpleTree, "data/randomTree30T_LeavesTagged.tgf");
            
            simpleTree = TgfTreeFactory.readStringTreeFromFile("data/randomTree30.tgf");
            leafCounter.reset();
            leafCounter.walk(simpleTree.getRoot());
            System.out.println("randomTree30.tgf leaf count:" + leafCounter.getLeafCount());

            simpleTree = TgfTreeFactory.readStringTreeFromFile("data/randomTree30.tgf");
            FindHeightWalker<Pair<String, Object>> findHeightWalker = new FindHeightWalker<Pair<String, Object>>();
            int height = findHeightWalker.walk(simpleTree.getRoot());
            System.out.println("randomTree30.tgf height:" + height);
        }
        catch( Exception e )
        {
            e.printStackTrace();
            Assert.assertFalse(true);
        }
    }
}
